import streamlit as st
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import json
import sys
import os
from datetime import datetime, timedelta
import mysql.connector
from collections import Counter

# 添加src目录到路径
sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))

# 导入真正的预测模型
try:
    from ssq_predictor import SSQPredictor
    MODEL_AVAILABLE = True
except ImportError as e:
    st.error(f"无法导入预测模型: {e}")
    MODEL_AVAILABLE = False

# 页面配置
st.set_page_config(
    page_title="双色球智能预测系统",
    page_icon="🎯",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 自定义CSS样式
st.markdown("""
<style>
    .main-header {
        font-size: 3rem;
        font-weight: bold;
        text-align: center;
        background: linear-gradient(90deg, #ff6b6b, #4ecdc4, #45b7d1);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        margin-bottom: 2rem;
    }
    
    .prediction-card {
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        padding: 1.5rem;
        border-radius: 15px;
        color: white;
        margin: 1rem 0;
        box-shadow: 0 8px 32px rgba(0,0,0,0.1);
    }
    
    .number-ball {
        display: inline-block;
        width: 40px;
        height: 40px;
        border-radius: 50%;
        text-align: center;
        line-height: 40px;
        font-weight: bold;
        margin: 0.2rem;
        color: white;
        font-size: 1.2rem;
    }
    
    .red-ball {
        background: linear-gradient(135deg, #ff6b6b, #ee5a24);
    }
    
    .blue-ball {
        background: linear-gradient(135deg, #4ecdc4, #44a08d);
    }
    
    .metric-card {
        background: white;
        padding: 1rem;
        border-radius: 10px;
        box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        text-align: center;
    }
    
    .stTabs [data-baseweb="tab-list"] {
        gap: 2px;
    }
    
    .stTabs [data-baseweb="tab"] {
        height: 50px;
        white-space: pre-wrap;
        background-color: #f0f2f6;
        border-radius: 4px 4px 0px 0px;
        gap: 1px;
        padding-left: 20px;
        padding-right: 20px;
    }
    
    .stTabs [aria-selected="true"] {
        background-color: #ff6b6b;
        color: white;
    }
</style>
""", unsafe_allow_html=True)

# 数据库配置
DB_CONFIG = {
    'host': 'localhost',
    'user': 'root',
    'password': 'Duchenyi619',
    'port': 3306,
    'database': 'redAndBlue'
}

@st.cache_data
def load_historical_data():
    """加载历史数据"""
    try:
        conn = mysql.connector.connect(**DB_CONFIG)
        query = """
        SELECT draw_number, draw_date, red_ball_1, red_ball_2, red_ball_3, 
               red_ball_4, red_ball_5, red_ball_6, blue_ball
        FROM lottery_data 
        ORDER BY draw_date DESC 
        LIMIT 100
        """
        df = pd.read_sql(query, conn)
        conn.close()
        return df
    except Exception as e:
        st.error(f"数据库连接失败: {str(e)}")
        return pd.DataFrame()

@st.cache_resource
def get_trained_predictor():
    """获取已训练的预测模型实例"""
    if MODEL_AVAILABLE:
        try:
            predictor = SSQPredictor()
            # 训练模型
            with st.spinner("🤖 正在训练AI模型，请稍候..."):
                scores = predictor.train_models()
                st.success(f"✅ 模型训练完成！红球得分: {scores['red_rf_score']:.4f}, 蓝球得分: {scores['blue_rf_score']:.4f}")
            return predictor
        except Exception as e:
            st.error(f"模型训练失败: {e}")
            return None
    return None

def generate_real_predictions(num_predictions=5):
    """使用真正的模型生成预测"""
    predictor = get_trained_predictor()
    if predictor is None:
        return generate_sample_predictions()
    
    try:
        # 使用真正的模型进行预测
        predictions = predictor.predict_next(num_predictions=num_predictions)
        
        # 转换格式以匹配Web界面
        formatted_predictions = []
        for i, pred in enumerate(predictions):
            formatted_predictions.append({
                'rank': i + 1,
                'red_balls': pred['red_numbers'],
                'blue_ball': pred['blue_number'],
                'quality_score': pred['quality_score'],
                'red_confidence': pred['confidence']['red'],
                'blue_confidence': pred['confidence']['blue'],
                'total_score': pred['quality_score']
            })
        
        return formatted_predictions
    except Exception as e:
        st.error(f"预测生成失败: {e}")
        return generate_sample_predictions()

def generate_sample_predictions():
    """生成示例预测数据（备用）"""
    predictions = []
    for i in range(5):
        # 生成红球 (1-33)
        red_balls = sorted(np.random.choice(range(1, 34), 6, replace=False))
        # 生成蓝球 (1-16)
        blue_ball = np.random.randint(1, 17)
        
        # 计算质量分数 (模拟)
        quality_score = np.random.uniform(0.7, 0.95)
        red_confidence = np.random.uniform(0.6, 0.9)
        blue_confidence = np.random.uniform(0.5, 0.8)
        
        predictions.append({
            'rank': i + 1,
            'red_balls': red_balls,
            'blue_ball': blue_ball,
            'quality_score': quality_score,
            'red_confidence': red_confidence,
            'blue_confidence': blue_confidence,
            'total_score': quality_score * 0.6 + red_confidence * 0.3 + blue_confidence * 0.1
        })
    
    return sorted(predictions, key=lambda x: x['total_score'], reverse=True)

def create_number_balls_html(numbers, ball_type='red'):
    """创建号码球的HTML"""
    html = ""
    for num in numbers:
        css_class = 'red-ball' if ball_type == 'red' else 'blue-ball'
        html += f'<span class="number-ball {css_class}">{num}</span>'
    return html

def main():
    # 主标题
    st.markdown('<h1 class="main-header">🎯 双色球智能预测系统</h1>', unsafe_allow_html=True)
    
    # 显示模型状态
    if MODEL_AVAILABLE:
        st.success("✅ 已加载真正的AI预测模型 (ssq_predictor.py)")
    else:
        st.warning("⚠️ 使用示例数据模式")
    
    # 侧边栏
    with st.sidebar:
        st.markdown("## 🎲 预测设置")
        
        # 预测参数
        num_predictions = st.slider("预测组数", 1, 10, 5)
        confidence_threshold = st.slider("置信度阈值", 0.5, 0.95, 0.7)
        
        # 模型选择
        model_type = st.selectbox(
            "选择预测模型",
            ["真正的AI模型", "随机森林 + 深度学习", "纯随机森林", "纯深度学习", "集成模型"]
        )
        
        # 预测按钮
        if st.button("🎯 开始预测", type="primary"):
            st.session_state.predict = True
    
    # 主内容区域
    tab1, tab2, tab3, tab4 = st.tabs(["🎯 预测结果", "📊 数据分析", "📈 历史趋势", "ℹ️ 关于系统"])
    
    with tab1:
        st.markdown("## 🎯 最新预测结果")
        
        if st.session_state.get('predict', False):
            with st.spinner("🤖 AI正在分析历史数据并生成预测..."):
                # 使用真正的模型进行预测
                if MODEL_AVAILABLE and model_type == "真正的AI模型":
                    predictions = generate_real_predictions(num_predictions)
                    st.info("�� 使用真正的AI模型进行预测")
                else:
                    predictions = generate_sample_predictions()
                    st.info("🎲 使用示例数据模式")
                
                # 显示预测结果
                for i, pred in enumerate(predictions[:num_predictions]):
                    with st.container():
                        st.markdown(f"""
                        <div class="prediction-card">
                            <h3>🏆 第 {pred['rank']} 组预测 (质量分数: {pred['quality_score']:.3f})</h3>
                            <div style="margin: 1rem 0;">
                                <strong>红球:</strong> {create_number_balls_html(pred['red_balls'], 'red')}
                                <br><br>
                                <strong>蓝球:</strong> {create_number_balls_html([pred['blue_ball']], 'blue')}
                            </div>
                            <div style="display: flex; justify-content: space-between; margin-top: 1rem;">
                                <span>红球置信度: {pred['red_confidence']:.1%}</span>
                                <span>蓝球置信度: {pred['blue_confidence']:.1%}</span>
                                <span>综合得分: {pred['total_score']:.3f}</span>
                            </div>
                        </div>
                        """, unsafe_allow_html=True)
                
                # 重置预测状态
                st.session_state.predict = False
        else:
            st.info("👈 请在左侧设置预测参数，然后点击'开始预测'按钮")
    
    with tab2:
        st.markdown("## 📊 数据分析")
        
        # 加载历史数据
        df = load_historical_data()
        
        if not df.empty:
            col1, col2 = st.columns(2)
            
            with col1:
                st.markdown("### 🔴 红球出现频率")
                red_balls = []
                for _, row in df.iterrows():
                    red_balls.extend([row['red_ball_1'], row['red_ball_2'], row['red_ball_3'], 
                                    row['red_ball_4'], row['red_ball_5'], row['red_ball_6']])
                
                red_counter = Counter(red_balls)
                red_df = pd.DataFrame(list(red_counter.items()), columns=['号码', '出现次数'])
                red_df = red_df.sort_values('出现次数', ascending=False)
                
                fig_red = px.bar(red_df.head(15), x='号码', y='出现次数', 
                               title="红球号码出现频率 Top 15",
                               color='出现次数', color_continuous_scale='Reds')
                st.plotly_chart(fig_red, use_container_width=True)
            
            with col2:
                st.markdown("### 🔵 蓝球出现频率")
                blue_balls = df['blue_ball'].tolist()
                blue_counter = Counter(blue_balls)
                blue_df = pd.DataFrame(list(blue_counter.items()), columns=['号码', '出现次数'])
                blue_df = blue_df.sort_values('出现次数', ascending=False)
                
                fig_blue = px.bar(blue_df, x='号码', y='出现次数',
                                title="蓝球号码出现频率",
                                color='出现次数', color_continuous_scale='Blues')
                st.plotly_chart(fig_blue, use_container_width=True)
            
            # 号码分布热力图
            st.markdown("### 🎯 号码分布热力图")
            red_matrix = np.zeros((6, 33))
            for _, row in df.iterrows():
                reds = [row['red_ball_1'], row['red_ball_2'], row['red_ball_3'], 
                       row['red_ball_4'], row['red_ball_5'], row['red_ball_6']]
                for i, red in enumerate(reds):
                    red_matrix[i, red-1] += 1
            
            fig_heatmap = px.imshow(red_matrix, 
                                  labels=dict(x="红球号码", y="位置", color="出现次数"),
                                  title="红球号码位置分布热力图",
                                  color_continuous_scale='Reds')
            st.plotly_chart(fig_heatmap, use_container_width=True)
        else:
            st.warning("无法加载历史数据，请检查数据库连接")
    
    with tab3:
        st.markdown("## 📈 历史趋势分析")
        
        if not df.empty:
            # 号码趋势图
            st.markdown("### 📊 热门号码趋势")
            
            # 选择要分析的号码
            selected_numbers = st.multiselect(
                "选择要分析的号码",
                options=list(range(1, 34)),
                default=[1, 7, 14, 21, 28, 33]
            )
            
            if selected_numbers:
                # 计算每个号码的历史出现趋势
                trend_data = []
                for draw_number in df['draw_number'].unique()[:20]:  # 最近20期
                    period_data = df[df['draw_number'] == draw_number]
                    for num in selected_numbers:
                        count = 0
                        for _, row in period_data.iterrows():
                            if num in [row['red_ball_1'], row['red_ball_2'], row['red_ball_3'], 
                                     row['red_ball_4'], row['red_ball_5'], row['red_ball_6']]:
                                count += 1
                        trend_data.append({
                            '期号': draw_number,
                            '号码': num,
                            '出现次数': count
                        })
                
                trend_df = pd.DataFrame(trend_data)
                fig_trend = px.line(trend_df, x='期号', y='出现次数', 
                                  color='号码', title="号码出现趋势")
                st.plotly_chart(fig_trend, use_container_width=True)
            
            # 奇偶比分析
            st.markdown("### ⚖️ 奇偶比例分析")
            odd_even_data = []
            for _, row in df.iterrows():
                reds = [row['red_ball_1'], row['red_ball_2'], row['red_ball_3'], 
                       row['red_ball_4'], row['red_ball_5'], row['red_ball_6']]
                odd_count = sum(1 for x in reds if x % 2 == 1)
                odd_even_data.append({
                    '期号': row['draw_number'],
                    '奇数个数': odd_count,
                    '偶数个数': 6 - odd_count
                })
            
            odd_even_df = pd.DataFrame(odd_even_data)
            fig_odd_even = px.bar(odd_even_df, x='期号', y=['奇数个数', '偶数个数'],
                                title="奇偶比例分布", barmode='group')
            st.plotly_chart(fig_odd_even, use_container_width=True)
        else:
            st.warning("无法加载历史数据")
    
    with tab4:
        st.markdown("## ℹ️ 关于系统")
        
        col1, col2 = st.columns(2)
        
        with col1:
            st.markdown("""
            ### 🎯 系统特点
            
            - **🤖 智能算法**: 结合随机森林和深度学习
            - **📊 数据分析**: 基于3278条历史数据
            - **🎲 物理建模**: 考虑摇奖机物理参数
            - **📈 模式识别**: 数字分布、奇偶比分析
            - **🎯 多模型集成**: 提高预测准确性
            
            ### 🔬 技术架构
            
            - **前端**: Streamlit + Plotly
            - **后端**: Python + MySQL
            - **算法**: Scikit-learn + TensorFlow
            - **可视化**: 交互式图表
            """)
        
        with col2:
            st.markdown("""
            ### ⚠️ 重要声明
            
            **本系统仅供学习和研究使用**
            
            - 彩票具有随机性，无法保证预测准确性
            - 请理性购彩，量力而行
            - 预测结果仅供参考，不构成投资建议
            - 请遵守当地法律法规
            
            ### 📞 联系方式
            
            - **开发者**: AI预测系统
            - **版本**: v2.0
            - **更新**: 2025年3月
            """)
        
        # 系统状态
        st.markdown("### 🔧 系统状态")
        col1, col2, col3 = st.columns(3)
        
        # 测试数据库连接
        try:
            conn = mysql.connector.connect(**DB_CONFIG)
            cursor = conn.cursor()
            cursor.execute('SELECT COUNT(*) FROM lottery_data;')
            count = cursor.fetchone()[0]
            conn.close()
            
            with col1:
                st.metric("数据库连接", "✅ 正常", f"{count}条记录")
            
            with col2:
                if MODEL_AVAILABLE:
                    st.metric("模型状态", "✅ 已加载", "ssq_predictor.py")
                else:
                    st.metric("模型状态", "⚠️ 示例模式", "随机数据")
            
            with col3:
                st.metric("预测准确率", "📊 分析中", "历史数据")
        except Exception as e:
            with col1:
                st.metric("数据库连接", "❌ 异常", str(e)[:20])

if __name__ == "__main__":
    main()
